简介
JNI是Java Native Interface的英文缩写, 中文翻译为本地调用, 自从Java 1.1开始就成为了Java标准的一部分.
C/C++是系统级的编程语言, 可以用来开发任何和系统相关的程序和类库, 但是Java本身编写底层的应用比较难实现, 使用JNI可以调用现有的本地库, 极大地灵活了Java的开发.
C/C++的效率是目前最好的语言, 可以使用C/C++来实现一些实时性非常高的部分. C/C++和Java本身都是非常流行的编程语言, 一些大型软件中经常使用语言之间的混合编程
新建一个HelloJNI类
1 | package com.jianganwei.demo; |
代码的静态代码块在这个类被类加载器加载的时候调用了System.loadLibrary()方法来加载一个native库“HelloJNI”(这个库中实现了sayHello函数)。这个库在windows品台上对应了“helloJNI.dll”,而在类UNIX平台上对应了“libhelloJNI.so”。这个库应该包含在Java的库路径(使用java.library.path系统变量表示)上,否则这个上面的程序会抛出UnsatisfiedLinkError错误。你应该使用VM的参数-Djava.library.path=path_to_lib来指定包含native库的路径。
接下来,我们使用native关键字将sayHello()方法声明为本地实例方法,这就很明显地告诉JVM:这个方法实现在另外一个语言中(C/C++),请去那里寻找他的实现。注意,一个native方法不包含方法体,只有声明。上面代码中的main方法实例化了一个HelloJJNI类的实例,然后调用了本地方法sayHello()。
编译得到.class文件
javac HelloJNI.java 获得build一下项目.class 文件 就在target/classes中
链接生成头文件
1 | javah -classpath target/classes -d ./jni com.jianganwei.demo.HelloJNI |
会在./jni 这个目录下生成 jni/com_jianganwei_demo_HelloJNI.h 文件内容如下
1 |
|
在idea中配置一键生成头文件
编写c或c++代码c为.c c++为cpp文件
新建文件.c或.cpp文件,实现上一步头文件的接口
1 |
|
生成.o
1 |
|
上面是jdk的路径,window 下第2个路径有点不同进去jdk 目录看一下就好了
生成.so文件,win 为dll
1 | gcc -shared HelloJNI.o -o libHello.so |
最后把生成的so文件放到java.library.path
把so 文件放到某个目录下,或者配置运行时环境 -Djava.library.path=/home/jianganwei/IdeaProjects/Bemoan/lib 到so文件所在目录
最后
生成o 和so 文件可以合成一步
1 | gcc -fPIC -I"/opt/jdk1.8/jdk1.8.0_151/include" -I"/opt/jdk1.8/jdk1.8.0_151/include/linux" -shared -o ./lib/libHelloJNI.so jni/HelloJNI.c |
idea 配置一键生成